using System;
using System.IO;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;

namespace PlatformerCS
{
    public class GameBoard : Game
    {
        /* Graphics */
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;
        Texture2D texture, pixel;
        public static int WIDTH = 1500, HEIGHT = 900;

        /* Game components */
        Terrain terrainMgr;

        /* Game elements */

        PerlinNoise perlin;

        KeyboardState Kstate, prevKstate;
        SpriteFont font;

        Random rand;
        Player player;

        public GameBoard()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";

            IsMouseVisible = true;
            graphics.PreferredBackBufferWidth = WIDTH;
            graphics.PreferredBackBufferHeight = HEIGHT;
        }

        protected override void Initialize()
        {
            rand = new Random();
            perlin = new PerlinNoise(GraphicsDevice, this);
            player = new Player(this);

            base.Initialize();
        }

        protected override void LoadContent()
        {
            spriteBatch = new SpriteBatch(GraphicsDevice);
            texture = new Texture2D(GraphicsDevice, 2, 2);
            pixel = new Texture2D(GraphicsDevice, 1, 1);
            texture.SetData<Color>(new Color[4] { Color.White, Color.White, Color.White, Color.White });
            pixel.SetData<Color>(new Color[1] { Color.White });
            font = Content.Load<SpriteFont>("Fonts/Menu");
            terrainMgr = new Terrain(Content);
            base.LoadContent();
        }

        protected override void UnloadContent()
        {
            base.UnloadContent();
        }

        protected override void Update(GameTime gameTime)
        {
            prevKstate = Kstate;
            Kstate = Keyboard.GetState();

            player.Update();

            if (prevKstate.IsKeyUp(Keys.Enter) && Kstate.IsKeyDown(Keys.Enter))
                perlin.Generate();

            if (prevKstate.IsKeyUp(Keys.Escape) && Kstate.IsKeyDown(Keys.Escape))
                Exit();
            
            base.Update(gameTime);
        }

        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.White);
            // Draw world
            spriteBatch.Begin(SpriteBlendMode.AlphaBlend, SpriteSortMode.Deferred, SaveStateMode.SaveState, player.Camera.Transform);
            terrainMgr.Draw(spriteBatch);
            player.DrawWorld(spriteBatch);
            spriteBatch.End();

            // Draw stats (no affected by the transform matrix)
            spriteBatch.Begin();
            player.DrawStats(spriteBatch, gameTime);
            perlin.Draw(spriteBatch);
            spriteBatch.End();

            base.Draw(gameTime);
        }

        public void DrawLine(Vector2 point1, Vector2 point2)
        {
            float distance = Vector2.Distance(point1, point2);
            float angle = (float)Math.Atan2(point2.Y - point1.Y, point2.X - point1.X);

            spriteBatch.Draw(pixel, point1, null, Color.Black, angle, Vector2.Zero, new Vector2(distance, 1), SpriteEffects.None, 0);
        }

        void DrawPoint(Vector2 p)
        {
            spriteBatch.Draw(texture, p, Color.Black);
        }
    }
}
